import os
import os.path as osp
import shutil
import operator
import math

BASEDIR = osp.dirname(osp.abspath(__file__))

IMGSIZE_W, IMGSIZE_H = 4096, 4096

cls_dict = {
    'A': '0.0',
    'B': '1.0',
    'C': '2.0',
    'D': '3.0',
    'E': '4.0',
    'F': '5.0',
    'G': '6.0',
    'H': '7.0',
    'I': '8.0',
    'J': '9.0',
    'K': '10.0',
}

    
def get_distance(p1, p2):
    return ((p1[0]-p2[0])**2 + (p1[1]-p2[1])**2)**0.5


def convert_xy4_to_xywha(xy4, IMGSIZE_W, IMGSIZE_H):
    p1 = [eval(xy4[0]), eval(xy4[1])]
    p2 = [eval(xy4[2]), eval(xy4[3])]
    p3 = [eval(xy4[4]), eval(xy4[5])]
    p4 = [eval(xy4[6]), eval(xy4[7])]

    # 四个顶点取均值 中心点
    # cx = (eval(xy4[0]) + eval(xy4[2]) + eval(xy4[4]) + eval(xy4[6])) / 4
    # cy = (eval(xy4[1]) + eval(xy4[3]) + eval(xy4[5]) + eval(xy4[7])) / 4
    cx = sum((p1[0], p2[0], p3[0], p4[0])) / 4
    cy = sum((p1[1], p2[1], p3[1], p4[1])) / 4

    # 顶点连线距离 排序 对角线 长 宽
    distances = list()  # six combinations
    distances.append(get_distance(p1, p2))
    distances.append(get_distance(p1, p3))
    distances.append(get_distance(p1, p4))
    distances.append(get_distance(p2, p3))
    distances.append(get_distance(p2, p4))
    distances.append(get_distance(p3, p4))
    distances.sort()  # catercorner * 2, longer_edge * 2, shorter_edge * 2

    w = (distances[2] + distances[3]) / 2  # longer edge
    h = (distances[0] + distances[1]) / 2  # shorter edge

    # 求旋转角度 角度制
    pp1, pp2, pp3, pp4 = sorted([p1, p2, p3, p4], key=operator.itemgetter(1))  # 四个顶点排序，以最低处的顶点pp1为起点
    print(pp1 ,pp2, pp3, pp4)

    pp0 = pp2  # 设pp0为长边终点
    d = get_distance(pp1, pp0)
    temp = abs(d - w)  # d 与 w 的历史最小差距
    for ppi in [pp3, pp4]:
        d = get_distance(pp1, ppi)
        if abs(d - w) < temp:  # 若 基点到该点距离d 与 长边w 差距更小(更接近相等)
            temp = abs(d - w)  # 更新历史最小差距
            pp0 = ppi  # 切换终点
    print(pp0)

    dy = pp0[1] - pp1[1]  # 必然>=0
    dx = pp0[0] - pp1[0]  # +-

    if dy < 1e-6:
        angle = 0  # the angle needs to be int degree
    elif abs(dx) < 1e-6:
        angle = 90  
    else:
        angle = int(math.atan(dy/dx) * 180 / math.pi)
    
    # 在0-179之间
    if angle < 0:
        angle += 180

    # 归一化
    cx = cx / IMGSIZE_W
    cy = cy / IMGSIZE_H
    w = w / IMGSIZE_W
    h = h / IMGSIZE_H

    return cx, cy, w, h, angle


# ========================================================= main
path_result_log_txt = osp.join(BASEDIR, 'results.txt')
OUTDIR = osp.join(BASEDIR, 'pred_txts')
if osp.exists(OUTDIR):
    shutil.rmtree(OUTDIR)
else:
    os.makedirs(OUTDIR)
        
        
# 阅读results.txt
with open(path_result_log_txt, 'r') as fp:
    lines = fp.readlines()
for line in lines:
    path_img, cls_name, conf, *xy4 = line.strip().split()
    filename = path_img.split('/')[-1].split('.')[0]
    txt_name = filename + '.txt'

    # IMGSIZE_W, IMGSIZE_H = Image.open(path_img).size

    x, y, w, h, a = convert_xy4_to_xywha(xy4, IMGSIZE_W, IMGSIZE_H)

    one_box_str = cls_dict[cls_name] + ' ' + str(x) + ' ' + str(y) + ' ' + str(w) + ' ' + str(h) + ' ' + str(a) + '\n'
    with open(osp.join(OUTDIR, txt_name), 'a') as fp:
        fp.write(one_box_str)
